package xfsale.service.impl.j2ee;

import java.io.IOException;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.SQLException;

import org.apache.log4j.Logger;

import xfsale.exception.AppException;
import xfsale.packet.BaseRequest;
import xfsale.packet.BaseResponse;

public abstract class BaseService {

    private BaseRequest request;        //服务请求
    private BaseResponse response;      //服务应答
    protected PubSys sys;				//公用系统对象
    protected PubAcct acct;				//公用账户对象
    protected PubSerial serial;			//公用流水对象
    protected PubPriv priv;				//公用权限对象
    protected PubLog log;				//公用日志对象
    protected PubRule rule;				//公用规则对象
    protected Connection conn;			//数据库连接
    protected Logger logger = Logger.getLogger(BaseService.class);	//日志

    public BaseService(BaseRequest request, BaseResponse response) {
        if (request == null || response == null) {
            throw new IllegalArgumentException("请求和应答对象不能为空");
        }

        this.request = request;
        this.response = response;

        //获取数据库连接
        this.conn = PubConn.getConnection();

        //创建公用对象
        this.sys = new PubSys(conn);
        this.acct = new PubAcct(conn);
        this.serial = new PubSerial(conn);
        this.priv = new PubPriv(conn);
        this.log = new PubLog(conn);
        this.rule = new PubRule(conn);
    }

    //初始化
    protected void init() throws Exception {
        logger.info("开始初始化...");

        //设置事务不自动提交
        conn.setAutoCommit(false);

        try {
            //转换请求空字符串
            logger.debug("转换请求空字符串...");
            for (Field field : request.getClass().getFields()) {
                if (field.getType() == String.class) {
                    Object value = field.get(request);
                    if (value == null) {
                        field.set(request, "");
                    }
                }
            }
            logger.debug("转换请求空字符串成功.");
        } catch (IllegalAccessException e) {
            logger.error("转换请求空字符串失败.");
        }
    }

    //检查输入参数
    protected void checkData() throws Exception {
        logger.info("开始检查输入参数...");

        //检查返回代码
        if (!response.has("returnCode")) {
            throw new AppException("应答不包括returnCode属性");
        }

        //检查返回信息
        if (!response.has("returnMsg")) {
            throw new AppException("应答不包括returnMsg属性");
        }
    }

    //加载所需数据
    protected void load() throws Exception {
        logger.info("开始加载所需数据...");
    }

    //检查功能权限
    protected void checkPriv() throws Exception {
        logger.info("开始检查功能权限...");
    }

    //检查业务条件
    protected void checkCondition() throws Exception {
        logger.info("开始检查业务条件...");
    }

    //写入操作日志
    protected void writeLog() throws Exception {
        logger.info("开始写入操作日志...");
    }

    //业务处理
    protected void process() throws Exception {
        logger.info("开始业务处理...");
    }

    //执行
    public final void execute() throws Exception {
        try {
            //初始化
            init();

            //检查输入参数
            checkData();

            //初始化
            load();

            //检查功能权限
            checkPriv();

            //检查条件是否满足
            checkCondition();

            //功能处理
            process();

            //提交事务
            conn.commit();
        } catch (AppException e) {
            response.setString("returnCode", e.getErrorCode());
            response.setString("returnMsg", e.getErrorMsg());
            logger.error(e);
            conn.rollback();
        } catch (SQLException e) {
            response.setString("returnCode", AppException.ERROR_CODE_DB);
            response.setString("returnMsg", "数据库错误，请与系统维护人员联系");
            logger.error(e);
            conn.rollback();
        } catch (IOException e) {
            response.setString("returnCode", AppException.ERROR_CODE_IO);
            response.setString("returnMsg", "IO错误,请与系统维护人员联系");
            logger.error(e);
            conn.rollback();
        } catch (Exception e) {
            response.setString("returnCode", AppException.ERROR_CODE_RT);
            response.setString("returnMsg", "运行时错误,请与系统维护人员联系");
            logger.error(e);
            conn.rollback();
        } finally {
            //写入操作日志
            writeLog();

            //关闭数据库连接
            conn.close();
        }
    }
}
